---
title: Facets
---

Facets are a powerful tool for filtering and narrowing down search results on the Orama search engine.

With the Orama Faceted Search API, users can filter their search results by various criteria, such as category, price range, or other attributes, making it easier to find the information they need. Whether you're building a website, mobile app, or any other application, the Orama Faceted Search API is the perfect solution for adding faceted search functionality to your project.

Given the following Orama schema:

```js
import { create } from "@orama/orama";

const db = await create({
  schema: {
    title: "string",
    description: "string",
    categories: {
      primary: "string",
      secondary: "string",
    },
    rating: "number",
    isFavorite: "boolean",
  },
});
```

Orama will be able to generate facets at search-time based on the schema.
To do so, we need to specify the `facets` property in the `search` configuration:

```js
const results = await search(db, {
  term: "Movie about cars and racing",
  properties: ["description"],
  facets: {
    "categories.primary": {
      limit: 3,
      order: "DESC",
    },
    "categories.secondary": {
      limit: 2,
      order: "DESC",
    },
    rating: {
      ranges: [
        { from: 0, to: 3 },
        { from: 3, to: 7 },
        { from: 7, to: 10 },
      ],
    },
    isFavorite: {
      true: true,
      false: true,
    },
  },
});
```

This will generate the following result:

```js
{
  elapsed: ...,
  count: ...,
  hits: { ... },
  facets: {
    'categories.first': {
      count: 14,
      values: {
        'Action': 4,
        'Adventure': 3,
        'Comedy': 2,
      }
    },
    'categories.second': {
      count: 14,
      values: {
        'Cars': 4,
        'Racing': 3,
      }
    },
    rating: {
      count: 3,
      values: {
        '0-3': 5,
        '3-7': 15,
        '7-10': 80,
      }
    },
    isFavorite: {
      count: 2,
      values: {
        'true': 5,
        'false': 95,
      }
    },
  }
}
```

As you may have noticed, the `facets` property is an `object` that contains different
configurations depending on the property type specified in the schema.

## String facets

If a property is specified as `string` in the schema, the facet will accept the following
configuration:

| Property | Type     | Default | Description                                         |
| -------- | -------- | ------- | --------------------------------------------------- |
| `order`  | `string` | `DESC`  | Order of the values. Can be either `ASC` or `DESC`. |
| `limit`  | `number` | `10`    | Maximum number of values to return.                 |
| `offset` | `number` | `0`     | Number of values to skip.                           |

In the search result, `string` facets will be returned as an `object` with the following properties:

```js
{
  count: 14,            // Total number of values, now limited to 3 (size)
  values: {
    'Action': 4,        // Number of documents that have this value
    'Adventure': 3,     // Number of documents that have this value
    'Comedy': 2,        // Number of documents that have this value
  }
}
```

## Number facets

If a property is specified as `number` in the schema, the facet will accept the following
configuration:

| Property | Type    | Default | Description                  |
| -------- | ------- | ------- | ---------------------------- |
| `ranges` | `array` | `[]`    | Array of ranges to consider. |

Each range is an `object` with the following properties:

| Property | Type     | Description                 |
| -------- | -------- | --------------------------- |
| `from`   | `number` | Minimum value of the range. |
| `to`     | `number` | Maximum value of the range. |

In the search result, `number` facets will be returned as an `object` with the following properties:

```js
{
  count: 3,      // Total number of ranges
  values: {
    '0-3': 5,    // Number of documents that have a value between 0 and 3 (inclusive)
    '3-7': 15,   // Number of documents that have a value between 3 and 7 (inclusive)
    '7-10': 80,  // Number of documents that have a value between 7 and 10 (inclusive)
  }
}
```

Please note that the `from` and `to` values are **inclusive**. Note also that the order of the ranges
is guaranteed as specified in the configuration.

## Boolean facets

If a property is specified as `boolean` in the schema, the facet will accept the following
configuration:

| Property | Type      | Default | Description                         |
| -------- | --------- | ------- | ----------------------------------- |
| `true`   | `boolean` | `true`  | Whether to consider `true` values.  |
| `false`  | `boolean` | `true`  | Whether to consider `false` values. |

In the search result, `boolean` facets will be returned as an `object` with the following properties:

```js
{
  count: 2,       // Total number of values
  values: {
    'true': 5,    // Number of documents that have a `true` value
    'false': 95,  // Number of documents that have a `false` value
  }
}
```

## Enum facets

If a property is specified as `enum` in the schema, no configuration is required.
In the search result, `enum` facets will be returned as an `object` with the following properties:

```js
{
  count: 9,            // Total number of values
  values: {
    'Action': 4,        // Number of documents that have this value
    'Adventure': 3,     // Number of documents that have this value
    'Comedy': 2,        // Number of documents that have this value
  }
}
```

## How facets works on array fields

Orama treats each array element as a single element of the facet:

```javascript copy
const db = await create({
  schema: {
    name: "string[]",
  },
});
await insert(db, {
  name: ["Albus", "Percival Wulfric Brian"],
});

const results = await search(db, {
  facets: {
    name: {},
  },
});
```

`result.facets` is the following object:

```json
{
  "count": 2,
  "values": {
    "Albus": 1,
    "Percival Wulfric Brian": 1
  }
}
```
